const gulp = require('gulp');
const connect = require('gulp-connect');
const devConfig = require('./.dev.config.js')
const browserSync = require('browser-sync').create();
const {moveTo} = require('./build/utils.js')
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');

const PUBLISH_PATH = devConfig.publishPath;
const ADMIN_PUBLISH_PATH = devConfig.adminPublishPath;
const devComponents = devConfig.debugComponents ? devConfig.debugComponents : []
const devAdminComponents = devConfig.adminDebugComponents ? devConfig.adminDebugComponents : []
// 组件列表（假设我们要渲染这些组件）
var components = devConfig.allComponents;
var adminComponents = devConfig.adminAllComponents;
if(devComponents.length>0){
  components = components.filter((d) => {
    return devComponents.includes(d)
  })
}
if(devAdminComponents.length>0){
  adminComponents = adminComponents.filter((d) => {
    return devAdminComponents.includes(d)
  })
}

const server = {
    proxy: 'localhost:8080',  // 代理到 gulp-connect 的服务器
    port: 3000               // BrowserSync 的访问端口
}

// 启动本地服务器并启用热加载
gulp.task('serve', function(done) {
  connect.server({
    root: './dist',       // 指定服务器根目录
    livereload: true,    // 启用 livereload
    mime: {
        '.js': 'application/javascript'
    }
  });

  // 启动 BrowserSync
  browserSync.init(server);

  // 监听文件变化
  gulp.watch(
    ['src/components/**/*.vue', 'src/location/**/*.js', 'mocks/**/*.js'], 
    gulp.series('build', 'render', "location", 'generate-html','publish', 'reload'));
  // 监听文件变化
  gulp.watch(
    ['src/admin/**/*.vue'], 
    gulp.series('build-admin', 'publish-admin', 'generate-admin-html', 'reload'));
  
  // 监听 Ctrl+C 终止信号
  process.on('SIGINT', function() {
    connect.serverClose(); // 关闭 connect 服务器
    browserSync.exit();    // 关闭 BrowserSync
    done();                // 通知 Gulp 任务完成
  });
});

gulp.task('build-admin', function(){
    return new Promise((res,rej)=>{
        exec('node ./build/build.admin.js', function(err, stdout, stderr) {
          if (err) {
            console.error(`admin构建失败: ${stderr}`);
            rej(err);
          } else {
            console.log(`admin构建成功: ${stdout}`);
            res();
          }
        });
    })
})
// 构建任务
gulp.task('build', async function(done) {
    return new Promise((res,rej)=>{
        exec('yarn build', function(err, stdout, stderr) {
          if (err) {
            console.error(`构建失败: ${stderr}`);
            rej(err);
          } else {
            console.log(`构建成功: ${stdout}`);
            res();
          }
        });
    })
});
// 构建任务
gulp.task('render', async function(done) {
    return new Promise((res, rej)=>{
        exec('yarn render', function(err, stdout, stderr) {
          if (err) {
            console.error(`预渲染失败: ${stderr}`);
            rej(err);
          } else {
            console.log(`预渲染成功: ${stdout}`);
            res();
          }
        });
    })
});

gulp.task('location', async function(){
    console.log('location start...')
    return new Promise((res, rej)=>{
        exec('yarn location', function(err, stdout, stderr) {
          if (err) {
            console.error(`国际化处理失败: ${stderr}`);
            rej(err);
          } else {
            console.log(`国际化处理成功: ${stdout}`);
            res();
          }
        });
    })
})

gulp.task('publish', async function(){
    return new Promise((res, rej)=>{
        const distPath = path.join(__dirname, "dist");
        components.forEach((moudleName) => {
            const opath = path.join(distPath, moudleName, `${moudleName}.bundle*.js`)
            const ocsspath = path.join(distPath, moudleName, `${moudleName}.css`)
            const ohtmlpath = path.join(distPath, moudleName, `${moudleName}*.html`)
            moveTo(opath, path.join(PUBLISH_PATH, moudleName), {overwrite: true})
            moveTo(ocsspath, path.join(PUBLISH_PATH, moudleName), {overwrite: true})
            moveTo(ohtmlpath, path.join(PUBLISH_PATH, moudleName), {overwrite: true})
        })
        res()
    })
})

gulp.task('publish-admin', async function(){
    return new Promise((res, rej)=>{
        const distPath = path.join(__dirname, "dist", "admin");
        devAdminComponents.forEach((moudleName) => {
            const opath = path.join(distPath,`${moudleName}.bundle*.js`)
            const ocsspath = path.join(distPath,`${moudleName}.css`)
            moveTo(opath, path.join(ADMIN_PUBLISH_PATH, "admin"), {overwrite: true})
            moveTo(ocsspath, path.join(ADMIN_PUBLISH_PATH, "admin"), {overwrite: true})
        })
        res()
    })
})

// 生成预览页
// 定义生成 HTML 的任务
gulp.task('generate-html', (done) => {
    return new Promise((res,rej)=>{
        // 指定 dist 目录路径
        const distDir = path.resolve(__dirname, './dist');
        const htmltemplate = path.resolve(__dirname, './build/template.html');
        // 遍历 dist 目录，筛选出所有子文件夹（组件目录）
        const components = fs.readdirSync(distDir).filter(file => {
          const fullPath = path.join(distDir, file);
          return fs.statSync(fullPath).isDirectory();
        });  
        
        var scripts = "";
        var divs = "";
        var styles = "";
        components.forEach((component,i)=>{
            if( devComponents.length>0 && !devComponents.includes(component)){
                return;
            }
            const comId = 'wp-cc-' + String(Math.round(Math.random()*1000000000));
            const scriptSrc = `http://localhost:${server.port}/${component}/${component}.bundle.ori.js?${comId}`;//path.join(component, `${component}.bundle.js`);
            const scriptTag = `<script type="text/javascript" src="${scriptSrc}"></script>`;
            scripts += scriptTag + '\n';
            // $('body').append(scriptTag); // 添加到 <body> 末尾

            styles += `<link rel="stylesheet" id="dashicons-css" href="http://localhost:${server.port}/${component}/${component}.css?${comId}" media="all">`;
            
            const htmlpath = path.join(distDir, component, `${component}.ori.html`);
            const html = fs.readFileSync(htmlpath, 'utf8');

            divs += html.replace('<wpcc-component>', `<wpcc-component ${comId}>`);
            divs += `<script>(function(Vue){document.addEventListener('DOMContentLoaded', function(){const mountPoint=document.querySelector('[${comId}]');if(!mountPoint) return;const app = Vue.createApp(window.wpcc_components['${component}']);const componentInstance = app.mount(mountPoint);const componentRoot = componentInstance.\$el;mountPoint.parentNode.replaceChild(componentRoot, mountPoint);})})($wpcc_vue);</script>`;
        })
        const htmlContent = fs.readFileSync(htmltemplate, 'utf8');
        var htmlstr = htmlContent.replace('{{SCRIPTS_TAGS}}', scripts);
        htmlstr = htmlstr.replace('{{COMPONENTS_DIVS}}', divs);
        htmlstr = htmlstr.replace('{{STYLES}}', styles);
    
        const filepath = path.join(distDir, 'index.html');
        fs.writeFile(filepath, htmlstr, (err) => {
            if (err) {
                console.error('Error writing file:', err);
                rej()
            } else {
                console.log('index.html has been created successfully.');
                res()
            }
        });
    })
});

gulp.task('generate-admin-html', (done) => {
    return new Promise((res,rej)=>{
        const distDir = path.resolve(__dirname, './dist');
        const htmltemplate = path.resolve(__dirname, './build/admin_template.html');
        const htmlContent = fs.readFileSync(htmltemplate, 'utf8');
        var scripts = "";
        var divs = "";
        var styles = "";
        adminComponents.forEach((component,i)=>{
            const comId = 'wp-cc-' + String(Math.round(Math.random()*1000000000));
            divs += `<div id="${comId}"></div>`;

            const scriptSrc = `http://localhost:${server.port}/admin/${component}.bundle.js?${comId}`;//path.join(component, `${component}.bundle.js`);
            const scriptTag = `<script type="text/javascript" src="${scriptSrc}"></script>`;
            scripts += scriptTag + '\n';
            scripts += `<script>(function(Vue){document.addEventListener('DOMContentLoaded', function(){const mountPoint=document.getElementById('${comId}');if(!mountPoint) return;const app = Vue.createApp(window.wpcc_components_admin['${component}']);const componentInstance = app.mount(mountPoint);})})($wpcc_vue);</script>`;

            const stylesSrc = `http://localhost:${server.port}/admin/${component}.css?${comId}`;
            const stylesTag = `<link rel="stylesheet" id="dashicons-css" href="${stylesSrc}" media="all">`;
            styles += stylesTag + '\n';
        })

        var htmlstr = htmlContent.replace('{{SCRIPTS_TAGS}}', scripts);
        htmlstr = htmlstr.replace('{{COMPONENTS_DIVS}}', divs);
        htmlstr = htmlstr.replace('{{STYLES}}', styles);
        const filepath = path.join(distDir, 'index.html');
        fs.writeFile(filepath, htmlstr, (err) => {
            if (err) {
                console.error('Error writing file:', err);
                rej()
            } else {
                console.log('index.html has been created successfully.');
                res()
            }
        });
    })
})

// 刷新浏览器
gulp.task('reload', function(done) {
  browserSync.reload();
  done();
});

// 默认任务
gulp.task('admin', gulp.series('build-admin', 'publish-admin', 'generate-admin-html', 'serve'));
// 默认任务
gulp.task('default', gulp.series('build', 'render', 'generate-html',"location", 'publish', 'serve'));